package org.mobile.api.filter;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.mobile.api.Api;
import org.mobile.api.ApiFactory;
import org.mobile.api.IsvApi;
import org.mobile.api.exception.NoSuchApiException;
import org.mobile.model.util.Constants;
import org.mobile.model.util.ServiceUtil;

import net.sf.json.JSONObject;

import com.ucmed.alias.api.validator.Validator;
import com.ucmed.alias.api.validator.exception.ValidateException;
import com.ucmed.api.filter.chain.AbsFilterChain;
import com.ucmed.api.filter.exec.ApiExecFilter;


/**
 * @author sbwkl
 */
public class FilterChainImpl extends AbsFilterChain {

    private ApiFactory apiFactory;

    private Validator apiValidator;

    private boolean valid = true;

    public FilterChainImpl(List<ApiExecFilter> f) {
        super(f);
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public void setApiValidator(Validator apiValidator) {
        this.apiValidator = apiValidator;
    }

    public void setApiFactory(ApiFactory apiFactory) {
        this.apiFactory = apiFactory;
    }

    @Override
    public JSONObject doApi(JSONObject jsonReq,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        JSONObject jsonRes;
        String apiName = jsonReq.optString(Constants.TX);
        Integer id = jsonReq.optInt("hospitalId");
        String identity = getRealApiName(apiName);
        Api api = apiFactory.getApi(identity);
        jsonReq.put("api_name", apiName);
        JSONObject req = validateRequest(api, jsonReq.toString());
        jsonReq.put("api_name", apiName);
        jsonReq.put("hospitalId", id);
        jsonReq.put("user_type",
                jsonReq.optString(Constants.API_USER_TYPE, ""));
        jsonReq.put("session_id", jsonReq.optString("session_id"));
        JSONObject a = execute(api, req, request);
        jsonRes = validateResponse(api, apiName, a);
        return jsonRes;
    }

    private JSONObject validateRequest(Api api, String jsonReq)
            throws ValidateException {
        JSONObject req = JSONObject.fromObject(jsonReq);
        if(!(api instanceof IsvApi) || valid) {
            req = apiValidator.validate(jsonReq, true);
        }
        return req;
    }

    private JSONObject validateResponse(Api api, String apiName,
            JSONObject jsonRes) throws ValidateException {
        JSONObject res = jsonRes;
        if(!(api instanceof IsvApi) || valid) {
            jsonRes.put(Constants.API_NAME, apiName);
            res = apiValidator.validateResponse(jsonRes.toString());
        }
        return res;
    }

    private JSONObject execute(Api api, JSONObject req,
            HttpServletRequest request) throws NoSuchApiException {
        if (api == null) {
            throw new NoSuchApiException();
        }
        return api.execute(req);
    }

    private String getRealApiName(String apiName) {
        JSONObject p = new JSONObject();
        p.put("appApiName", apiName);
        JSONObject res = ServiceUtil.doService("processInterfaceService",
                "getInterfaceByApi", p);
        String identity = res.optString("identity");
        String an = StringUtils.isNotBlank(identity) ? identity : apiName;
        return an;
    }
}
